<template>
  <div class="samples-info-box tabs">
    <div v-if="activeName==='operation'||roleType==='adminRole'" class="tab-button-wrapper">
      <el-button size="mini" type="primary" @click="submit">确 认</el-button>
    </div>
    <div v-else-if="activeName==='data'&&activeNode!==''" class="set-roleData-wrapper">
      <div class="title-wrapper">
        <div class="title">数据权限列表</div>
        <el-button size="mini" plain type="success" @click="insertData">新 增</el-button>
      </div>
      <el-row class="setData-table">
        <el-col :span="24" class="samples-text-left samples-mb-10">
          <s-table
            :column="tableData.column"
            :data="tableData.data"
            :header-cell-class-name="headerCellClass"
            background
          />
        </el-col>
      </el-row>
    </div>
    <el-tabs v-model="activeName" class="samples-tabs">
      <el-tab-pane :label="opLabel" name="operation" class="role-tree-wrapper">
        <div class="title">请在以下勾选操作功能（可多选）</div>
        <el-tree
          ref="opTree"
          :props="{label:'name',children:'childList'}"
          class="tree"
          node-key="id"
          show-checkbox
          :data="opTreeProp"
          :default-expanded-keys="expendOp"
        />
      </el-tab-pane>
      <el-tab-pane v-if="roleType!=='adminRole'" :label="dataLabel" name="data" class="role-tree-wrapper">
        <div class="title">请在以下勾选操作对应的数据权限，并在右侧进行设置</div>
        <el-tree
          ref="dataTree"
          :props="{label:'name',children:'childList'}"
          class="tree"
          node-key="id"
          :data="dataTree"
          :default-expanded-keys="expendData"
          @node-click="clickNode"
        >
          <span
            slot-scope="{ node,data }"
            class="customNode"
            :class="[{'child':data.level===3},{'active':activeNode===data.id},{'hasData':data.hasAuthorityData}]"
          >{{ node.label }}</span>
        </el-tree>
      </el-tab-pane>
    </el-tabs>
    <el-dialog
      custom-class="samples-dialog"
      width="430px"
      top="50vh"
      :title="dialogTitle[dialogStatus]"
      :visible.sync="dialogVisible"
      :close-on-press-escape="false"
      :close-on-click-modal="false"
      :append-to-body="true"
      :before-close="handleClose"
    >
      <!-- 这里面是表单信息 -->
      <el-form ref="form" :model="dialogForm" :rules="dialogRules" label-width="140px" class="samples-dialog-form">
        <el-row>
          <el-col :span="24">
            <div class="setDataFormTitle">
              <span class="label">当前已选：</span>
              <span>{{ activeProduct }}</span>
            </div>
          </el-col>
        </el-row>
        <el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="字段：" prop="authorityFieldId">
                <el-select
                  v-model="dialogForm.authorityFieldId"
                  placeholder="请选择字段"
                  filterable
                  size="small"
                  style="width:100%"
                  @change="fieldChange"
                >
                  <el-option v-for="item in fieldList" :key="item.id" :label="item.fieldComment" :value="item.id" />
                </el-select>
                <template slot="error" slot-scope="scope">
                  <div class="sample-error-message">{{ scope.error }}</div>
                </template>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="操作类型：" prop="operation">
                <el-select v-model="dialogForm.operation" placeholder="请选择操作类型" size="small" style="width:100%">
                  <el-option v-for="item in operationList" :key="item.id" :label="item.label" :value="item.id" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="权限范围：" prop="dsType">
                <el-select
                  v-model="dialogForm.dsType"
                  placeholder="请选择权限范围"
                  filterable
                  size="small"
                  class="samples-must-declared"
                  style="width:100%"
                  @change="rangeChange"
                >
                  <el-option v-for="item in rangeList" :key="item.id" :label="item.label" :value="item.id" />
                </el-select>
                <template slot="error" slot-scope="scope">
                  <div class="sample-error-message">{{ scope.error }}</div>
                </template>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row v-show="showUser||showDept">
            <div class="rangeWrapper" :class="{active:showUser}">
              <el-select v-model="dsScope" multiple filterable placeholder="请选择用户" size="small" class="user">
                <el-option
                  v-for="item in userList"
                  :key="item.userId"
                  :label="item.usernameAndPhone"
                  :value="item.userId"
                />
              </el-select>
            </div>
            <div class="rangeWrapper" :class="{active:showDept}">
              <select-tree ref="selectTree" :tree-data="deptList" :tree-props="{label:'name'}" :tree-width="treeWidth" />
            </div>
          </el-row>
        </el-row>
      </el-form>
      <!-- 这里面是表单信息 -->
      <el-row class="samples-dialog-footer">
        <el-button size="small" type="primary" class="samples-float-right" @click="submitForm">确 认</el-button>
        <el-button
          size="small"
          type="primary"
          plain
          class="samples-float-right"
          style="margin-right:20px"
          @click="handleClose"
        >取 消</el-button>
      </el-row>
    </el-dialog>
  </div>
</template>

<script>
const setDataApiMap = {
  insert: 'addDataRoleApi',
  edit: 'editDataRoleApi'
}
const msgMap = {
  insert: '新增成功',
  edit: '编辑成功'
}
// 判断组件该调用哪一个api.js的Map
const apiMap = {
  adminRole,
  mgrRole
}
import * as adminRole from '@/api/maintainMag/operateRole'
import * as mgrRole from '@/api/tenantManage/role'
import sTable from '@/components/STable/s-table'
import selectTree from '@/components/SelectTree'
export default {
  components: { sTable, selectTree },
  props: {
    // admin平台的角色还是mgr平台的角色，根据平台构建页面
    roleType: {
      type: String,
      default: 'adminRole'
    },
    dataTreeProp: {
      type: Array,
      default: () => {
        return []
      }
    },
    opLabel: {
      type: String,
      default: ''
    },
    dataLabel: {
      type: String,
      default: ''
    },
    // 操作树被选中的id
    opChecked: {
      type: Array,
      default: () => {
        return []
      }
    },
    opTreeProp: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 默认展开第一级
    expendOp: {
      type: Array,
      default: () => {
        return []
      }
    },
    expendData: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 操作权限树确定的api，每个页面都有不同的接口，所以必须传
    opSubmitApi: {
      type: String,
      default: '',
      required: true
    },
    // 角色id
    roleId: {
      type: [String, Number],
      default: ''
    },
    deptId: {
      type: [String, Number],
      default: ''
    },
    // 角色名称
    roleName: {
      type: String,
      default: ''
    }
  },

  data() {
    return {
      // 组件所用的api文件
      compApi: '',
      // 数据树
      dataTree: [],
      activeName: 'operation',
      // 被选中的节点
      activeNode: '',
      // 当前产品路径
      activeProduct: '',
      // 指定权限范围
      dsScope: [],
      // 权限人员
      userList: [],
      // 权限部门
      deptList: [],
      treeWidth: '',
      // 操作类型列表
      operationList: [{ id: 1, label: '包含' }],
      // 字段列表
      fieldList: [],
      // 权限范围列表，根据字段的值，赋值下面的范围
      rangeList: [],
      // 人员范围
      userRange: [
        { id: 5, label: '全部人员' },
        { id: 1, label: '本人' },
        { id: 2, label: '指定用户' }
      ],
      // 组织机构范围
      deptRange: [{ id: 3, label: '本机构' }, { id: 4, label: '指定部门' }],
      // 选择指定人员展开
      showUser: false,
      // 选择指定部门展开
      showDept: false,
      dialogStatus: 'insert',
      dialogTitle: {
        edit: '编辑权限',
        insert: '新增权限'
      },
      dialogVisible: false, // 弹出框状态
      // 表单
      dialogForm: {
        authorityFieldId: '',
        dsType: '',
        dsScope: '',
        productId: '',
        roleId: '',
        id: '',
        operation: 1,
        roleProductId: '',
        type: ''
      },
      dialogRules: {
        authorityFieldId: [
          { required: true, message: '请选择字段', trigger: 'change' }
        ],
        operation: [
          { required: true, message: '请选择操作类型', trigger: 'change' }
        ],
        dsType: [
          { required: true, message: '请选择权限范围', trigger: 'change' }
        ]
      },
      // 数据权限表格
      tableData: {
        column: [
          {
            prop: 'sysProductAuthorityFieldComment',
            label: '字段名称',
            width: '140'
          },
          {
            label: '操作类型',
            width: '140',
            render: (h, scope) => {
              return <div>包含</div>
            }
          },
          {
            prop: 'dsScope',
            label: '权限范围'
          },
          {
            label: '操作',
            width: '104',
            render: (h, scope) => {
              return (
                <div>
                  <el-button
                    type='text'
                    size='small'
                    onClick={() => {
                      this.editData(scope.row.id)
                    }}
                  >
                    编 辑
                  </el-button>
                  <s-popver
                    popLeft={true}
                    iconName='question'
                    btnMsg='删除'
                    onSubmit={() => {
                      this.delData(scope.row.id)
                    }}
                  />
                </div>
              )
            }
          }
        ],
        data: [],
        options: {
          boundariesElement: 'scrollParent'
        }
      }
    }
  },

  computed: {},

  mounted() {
    this.compApi = apiMap[this.roleType]
    this.dataTree = this.dataTreeProp
    this.$refs.opTree.setCheckedKeys(this.opChecked)
    if (this.roleType !== 'adminRole') {
      this.getDeptList(Number(this.roleId))
      this.getUserList()
    }
  },

  methods: {
    // 字段修改带动权限范围修改
    fieldChange(id) {
      this.rangeList = []
      this.dialogForm.dsType = ''
      this.showDept = false
      this.showUser = false
      const type = this.fieldList.find(item => {
        return item.id === id
      })
      type.fieldType === 1
        ? (this.rangeList = this.userRange)
        : (this.rangeList = this.deptRange)
    },
    // 表头样式
    headerCellClass({ row, column, rowIndex, columnIndex }) {
      if (column.type == 'index') {
        return 'indexTableHeaderStyle'
      } else if (column.type == 'selection') {
        return ''
      } else {
        return 'samples-header-cell'
      }
    },
    // 关闭弹窗
    handleClose(done) {
      this.dialogVisible = false
      this.$refs['form'].resetFields()
      this.$refs.selectTree.clearData()
      this.showDept = false
      this.showUser = false
      this.dsScope = []
    },
    // 获取字段列表
    getFieldList(id) {
      this.compApi.getAuthorityFieldListApi({ sysProductId: id }).then(res => {
        if (res.code === 1) {
          this.fieldList = res.data
        }
      })
    },
    // 获取指定部门列表
    getDeptList(id) {
      this.compApi.deptListApi({ roleId: id }).then(response => {
        if (response.code == 1) {
          this.deptList = response.data
          this.delDepListChildren(this.deptList)
        }
      })
    },
    // 清除掉children为空的数据，为了级联组件的渲染
    delDepListChildren(res) {
      res.forEach(item => {
        if (item.children !== null) {
          if (item.children.length === 0) {
            delete item.children
          } else {
            this.delDepListChildren(item.children)
          }
        }
      })
    },
    // 获取指定人员列表
    getUserList() {
      this.compApi
        .userListApi({ name: '', deptId: this.deptId })
        .then(response => {
          if (response.code == 1) {
            this.userList = response.data
          }
        })
    },
    // 提交弹窗表单
    submitForm() {
      this.$refs['form'].validate(async valid => {
        if (valid) {
          try {
            await this.checkRange()
            this.compApi[setDataApiMap[this.dialogStatus]](
              this.dialogForm
            ).then(res => {
              if (res.code === 1) {
                this.$notify({
                  showClose: true,
                  title: '成功',
                  message: msgMap[this.dialogStatus],
                  type: 'success',
                  duration: '3000'
                })
                if (this.tableData.data.length === 0) {
                  this.dialogForm.roleProductId = res.data.roleProductId
                  this.setNodeState(
                    this.dataTree,
                    this.dialogForm.productId,
                    true
                  )
                }
                this.handleClose()
                this.getTableData()
              } else {
                this.$notify({
                  showClose: true,
                  title: '警告',
                  message: res.msg,
                  type: 'warning',
                  duration: '3000'
                })
              }
            })
          } catch (error) {
            this.$notify({
              showClose: true,
              title: '警告',
              message: '请选择具体权限范围!',
              type: 'warning',
              duration: '3000'
            })
          }
        }
      })
    },
    // 校验权限范围是否选择
    checkRange() {
      // 设置表单数据
      this.dataLabel.includes('页面')
        ? (this.dialogForm.type = 1)
        : (this.dialogForm.type = 2)
      return new Promise((resolve, reject) => {
        switch (this.dialogForm.dsType) {
          case 2: {
            this.dialogForm.dsScope = this.dsScope.join(',')
            this.dialogForm.dsScope === '' ? reject() : resolve()
            break
          }
          case 4: {
            this.dialogForm.dsScope = this.$refs.selectTree.checkIdList.join(
              ','
            )
            this.dialogForm.dsScope === '' ? reject() : resolve()
            break
          }
          default: {
            this.dialogForm.dsScope = ''
            resolve()
          }
        }
      })
    },
    // 新增数据权限
    insertData() {
      this.dialogStatus = 'insert'
      this.dialogVisible = true
    },
    // 编辑数据权限
    editData(id) {
      this.compApi.detailDataRoleApi({ id: id }).then(res => {
        if (res.code === 1) {
          this.dialogVisible = true
          this.dialogStatus = 'edit'
          this.$nextTick(() => {
            this.dialogForm.id = id
            this.dialogForm.authorityFieldId =
              res.data.sysProductAuthorityFieldId
            this.fieldChange(this.dialogForm.authorityFieldId)
            this.dialogForm.dsType = res.data.dsType
            res.data.dsScope !== ''
              ? (this.dsScope = res.data.dsScope.split(','))
              : (this.dsScope = [])
            this.rangeChange(res.data.dsType)
            if (res.data.dsType === 2) {
              for (const i in this.dsScope) {
                this.dsScope[i] = Number(this.dsScope[i])
              }
            } else if (res.data.dsType === 4) {
              this.$refs.selectTree.setData(this.dsScope)
            }
          })
        } else {
          this.$notify({
            showClose: true,
            title: '警告',
            message: res.msg,
            type: 'warning',
            duration: '3000'
          })
        }
      })
    },
    delData(id) {
      this.compApi.delDataRoleApi({ id: id }).then(res => {
        if (res.code === 1) {
          this.$notify({
            showClose: true,
            title: '成功',
            message: '删除权限点成功',
            type: 'success',
            duration: '3000'
          })
          if (this.tableData.data.length === 1) {
            this.dialogForm.roleProductId = res.data.roleProductId
            this.setNodeState(this.dataTree, this.dialogForm.productId, false)
          }
          this.getTableData()
        } else {
          this.$notify({
            showClose: true,
            title: '警告',
            message: res.msg,
            type: 'warning',
            duration: '3000'
          })
        }
      })
    },
    // 选择range联动
    rangeChange(val) {
      this.treeWidth = '240px'
      if (val === 2) {
        this.showUser = true
        this.showDept = false
      } else if (val === 4) {
        this.showDept = true
        this.showUser = false
      } else {
        this.showDept = false
        this.showUser = false
      }
    },
    // 数据权限，点击节点选中
    clickNode(data, node) {
      // 根据level判断是否是叶子节点
      if (data.level === 3) {
        this.activeNode = data.id
        const list = []
        this.findParent(node, list)
        this.activeProduct = list.join('/')
        this.dialogForm.roleId = this.roleId
        this.dialogForm.productId = data.id
        this.dialogForm.roleProductId = data.roleProductId
        this.getTableData()
        this.getFieldList(data.id)
      }
    },
    // 查找产品路径
    findParent(node, list) {
      list.unshift(node.data.name)
      if (node.level > 1) {
        this.findParent(node.parent, list)
      }
    },
    // 获取数据权限表格
    getTableData() {
      if (this.dialogForm.roleProductId === null) {
        this.tableData.data = []
      } else {
        this.compApi
          .getTableDataApi(this.dialogForm.roleProductId)
          .then(res => {
            if (res.code === 1) {
              this.tableData.data = res.data
            }
          })
      }
    },
    // 根据列表里是否有数据设置左边的树的节点的颜色
    setNodeState(arry, id, flag) {
      for (const i in arry) {
        if (arry[i].id === id) {
          arry[i].hasAuthorityData = flag
          arry[i].roleProductId = this.dialogForm.roleProductId
          return
        } else if (arry[i].childList.length > 0) {
          this.setNodeState(arry[i].childList, id, flag)
        }
      }
    },
    // 提交操作权限的修改
    submit(node, check) {
      const tree = this.$refs.opTree
      // 全选和半选的合并数组(node用来取roleProductId,key用来取productIds)
      const nodeList = tree.getCheckedNodes().concat(tree.getHalfCheckedNodes())
      const keyList = tree.getCheckedKeys().concat(tree.getHalfCheckedKeys())
      // 设置idList
      const productIds = []
      nodeList.forEach(item => {
        item.roleProductId !== null ? productIds.push(item.roleProductId) : ''
      })
      const param = {
        id: this.roleId,
        name: this.roleName,
        productIds: keyList
      }
      this.compApi[this.opSubmitApi](param).then(res => {
        if (res.code === 1) {
          this.$notify({
            showClose: true,
            title: '成功',
            message: '权限设置成功',
            type: 'success',
            duration: '3000'
          })
          this.$emit('closeTag')
        } else {
          this.$notify({
            showClose: true,
            title: '警告',
            message: res.msg,
            type: 'warning',
            duration: '3000'
          })
        }
      })
    }
  }
}
</script>
<style lang='scss' scoped>
.rangeWrapper {
  display: none;
  margin-left: 140px;
  width: cale(100%-140);
}
.user {
  width: 100%;
}
.rangeWrapper.active {
  display: block;
}
.setDataFormTitle {
  font-size: 14px;
  color: #606266;
  margin-bottom: 15px;
  .label {
    float: left;
    width: 140px;
    text-align: right;
    vertical-align: top;
    height: 100%;
    min-height: 32px;
  }
  > span:last-child {
    display: block;
    line-height: 16px;
    width: 100%;
    padding-left: 140px;
  }
}
</style>
